package com.mocha.bss.domain.org.repository;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.collection.ListUtil;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.coffee.core.CoffeeException;
import com.coffee.core.CoffeePage;
import com.coffee.mybatis.PageHandler;
import com.mocha.bss.config.BssResponseEnum;
import com.mocha.bss.domain.org.contoller.query.UserQuery;
import com.mocha.bss.domain.org.repository.entity.UserEntity;
import com.mocha.bss.domain.org.repository.mapper.MochaUserMapper;
import com.mocha.bss.domain.rbac.repository.RoleAdmRepository;
import com.mocha.bss.domain.rbac.repository.entity.RoleAdmEntity;
import com.mocha.bss.feign.bo.UserInfoBO;
import com.mocha.bss.org.bo.UserBO;
import com.mocha.bss.org.vo.UserVO;
import com.pinghua.mocha.basics.NumberKits;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * @author songkui
 * @since 2022-03-11
 */
@Service
@AllArgsConstructor
@Slf4j
public class MochaUserRepository extends ServiceImpl<MochaUserMapper, UserEntity>  {


    private final RoleAdmRepository roleAdmRepository;

    public Page<UserEntity> findByPage(Page page){
        return getBaseMapper().findByRole(page);
    }

    public CoffeePage<UserInfoBO> findByQuery(UserQuery<UserInfoBO> userQuery){
        Page<UserInfoBO> page = getBaseMapper().findByQuery(userQuery.buildPage(), userQuery);
        return PageHandler.buildCoffeePage(page);
    }

    public List<UserInfoBO> listByQuery(UserQuery<UserInfoBO> userQuery) {
        return getBaseMapper().listByQuery(userQuery);
    }

    public Set<UserInfoBO> listByExcept(Integer roleId){
        List<UserInfoBO> list = listByQuery(new UserQuery<>());
        return list.stream().filter(userInfoBO -> !roleId.equals(userInfoBO.getRoleId())).collect(Collectors.toSet());
    }

    public CoffeePage<UserVO> pageByQuery(UserQuery<UserVO> query) {
        Page<UserVO> page = getBaseMapper().pageByQuery(query.buildPage(), query);
        return PageHandler.buildCoffeePage(page);
    }

    public List<UserVO> listByQuery(UserBO userBO) {
        LambdaQueryWrapper<UserEntity> wrapper = new LambdaQueryWrapper<>();
        wrapper.like(StrUtil.isNotBlank(userBO.getNickname()),UserEntity::getNickname, userBO.getNickname())
                .like(StrUtil.isNotBlank(userBO.getMobile()),UserEntity::getMobile, userBO.getMobile())
                .like(StrUtil.isNotBlank(userBO.getWxName()),UserEntity::getWxName, userBO.getWxName())
                .like(StrUtil.isNotBlank(userBO.getWxOpenId()),UserEntity::getWxOpenId, userBO.getWxOpenId())
                .like(StrUtil.isNotBlank(userBO.getLoginCode()),UserEntity::getLoginCode, userBO.getLoginCode());
        List<UserEntity> userEntities = getBaseMapper().selectList(wrapper);
        List<UserVO> userVOS = BeanUtil.copyToList(userEntities, UserVO.class);
        return userVOS;
    }

    public void saveUser(UserBO userBO) {
        if (isExist(userBO)){
            throw new CoffeeException(BssResponseEnum.UserExist);
        }
        UserEntity userEntity = BeanUtil.copyProperties(userBO, UserEntity.class);
        this.save(userEntity);
        addUserAdmdiv(Long.parseLong(String.valueOf(userEntity.getId())), userBO.getAdmdivCode());
    }

    public void updateUser(UserBO userBO) {
        if (isExist(userBO)){
            throw new CoffeeException(BssResponseEnum.UserExist);
        }
        UserEntity userEntity = BeanUtil.copyProperties(userBO, UserEntity.class);
        this.updateById(userEntity);
        addUserAdmdiv(Long.parseLong(String.valueOf(userEntity.getId())), userBO.getAdmdivCode());
    }

    private boolean isExist(UserBO userBO) {
        List<UserEntity> list = this.lambdaQuery().select(UserEntity::getId)
                .eq(UserEntity::getLoginCode, userBO.getLoginCode())
                .or().eq(UserEntity::getMobile, userBO.getMobile()).list();

        if (CollectionUtil.isEmpty(list)){
            return false;
        }
        log.info("is Exist：list: {}", ArrayUtil.join(list.stream().map(UserEntity::getId).toArray(), ","));
        UserEntity entity = list.get(0);
        if (NumberKits.isMinus(userBO.getId())){
            return true;
        }
        return !userBO.getId().equals(entity.getId());
    }

    private void addUserAdmdiv(Long userId, String admdivCode) {
        if (StrUtil.isEmpty(admdivCode) || NumberKits.isMinus(userId)){
            return;
        }

        RoleAdmEntity oldRoleAdm = roleAdmRepository.getByRelatedId(userId);
        if (null == oldRoleAdm){
            RoleAdmEntity roleAdm = new  RoleAdmEntity();
            roleAdm.setAdmIds(admdivCode);
            roleAdm.setDataType(1);
            roleAdm.setRelatedId(userId);
            roleAdmRepository.save(roleAdm);
        }else {
            RoleAdmEntity entity = new RoleAdmEntity();
            entity.setId(oldRoleAdm.getId());
            entity.setAdmIds(admdivCode);
            roleAdmRepository.updateById(entity);
        }

    }


}

